package com.tian.service.impl;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.tian.config.RedisConfig;
import com.tian.convert.ChargeBalanceRecordReqDto;
import com.tian.dto.ChargeBalanceRecordDto;
import com.tian.dto.PayNotifyReqDto;
import com.tian.dto.WxPrePayReqDto;
import com.tian.enums.ResultCode;
import com.tian.enums.WxPayStatusEnum;
import com.tian.feign.ChargeBalanceRecordFeignClient;
import com.tian.service.PayService;
import com.tian.util.CommonResult;
import com.tian.util.ConstantUtil;
import com.tian.util.HttpRequestUtil;
import com.tian.util.RedisConstantPre;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * @date 2023年05月12日 18:06
 * 博客地址：<a href="http://woaijava.cc/">博客地址</a>
 */
@Slf4j
@Service
public class PayServiceImpl implements PayService {
    @Resource
    private ChargeBalanceRecordFeignClient chargeBalanceRecordFeignClient;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private WxPayService wxService;
    @Resource
    private RedisConfig redisConfig;

    @Override
    public CommonResult<WxPayMpOrderResult> prePay(WxPrePayReqDto wxPrePayReqDto, HttpServletRequest request) {
        wxPrePayReqDto.setIp(HttpRequestUtil.getIpAddr(request));
        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();

        String orderNo = ConstantUtil.ORDER_PRE + redisConfig.incr(RedisConstantPre.ORDER_NO_KEY);

        orderRequest.setOpenid(wxPrePayReqDto.getOpenId());
        orderRequest.setOutTradeNo(orderNo);
        orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
        orderRequest.setSpbillCreateIp(wxPrePayReqDto.getIp());
        orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(wxPrePayReqDto.getAmount().toPlainString()));
        orderRequest.setBody("充电付款");
        orderRequest.setNonceStr(String.valueOf(System.currentTimeMillis()));

        try {
            WxPayMpOrderResult wxPayMpOrderResult = wxService.createOrder(orderRequest);
            wxPrePayReqDto.setOrderNo(orderNo);
            CommonResult<Boolean> commonResult = chargeBalanceRecordFeignClient.prePay(wxPrePayReqDto);
            if (commonResult.getCode() == ResultCode.SUCCESS.getCode()) {
                return CommonResult.success(wxPayMpOrderResult);
            }
        } catch (WxPayException ex) {
            log.error("生成预付单失败：", ex);
        }
        return CommonResult.failed(ResultCode.FAILED);
    }

    @Override
    public String payNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayOrderNotifyResult result = wxService.parseOrderNotifyResult(xmlResult);
            // 结果正确
            String orderNo = result.getOutTradeNo();
            String tradeNo = result.getTransactionId();
            ChargeBalanceRecordReqDto chargeBalanceRecordReqDto = new ChargeBalanceRecordReqDto();
            chargeBalanceRecordReqDto.setOrderNo(orderNo);

            CommonResult<ChargeBalanceRecordDto> balanceRecordDtoCommonResult = chargeBalanceRecordFeignClient.selectByOrderNo(chargeBalanceRecordReqDto);
            if (balanceRecordDtoCommonResult.getCode() != ResultCode.SUCCESS.getCode()) {
                return WxPayNotifyResponse.fail("订单不存在" + orderNo);
            }
            //自己处理订单的业务逻辑，需要判断订单是否已经支付过，否则可能会重复调用
            if (balanceRecordDtoCommonResult.getData().getStatus() == WxPayStatusEnum.INIT.getStatus()) {
                //更新付款状态 用户付款成功----用户可用余额增加+充值记录单状态修改
                PayNotifyReqDto payNotifyReqDto = new PayNotifyReqDto();
                payNotifyReqDto.setRecordId(balanceRecordDtoCommonResult.getData().getId());
                payNotifyReqDto.setThirdTradeNo(tradeNo);
                chargeBalanceRecordFeignClient.wxPayNotify(payNotifyReqDto);
            }
            return WxPayNotifyResponse.success("处理成功!");
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因{}", e.getMessage());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }
}
